package com.whfc.openapi.api.fse.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.whfc.common.constant.QueueConst;
import com.whfc.common.enums.DevicePlatform;
import com.whfc.common.result.ListData;
import com.whfc.common.util.JSONUtil;
import com.whfc.common.util.MathUtil;
import com.whfc.fse.constant.FseCraneMeasurement;
import com.whfc.fse.dto.*;
import com.whfc.fse.enums.FseType;
import com.whfc.fse.enums.FseWarnRuleType;
import com.whfc.fse.param.FseCraneDataAddParam;
import com.whfc.fse.service.FseCraneDataService;
import com.whfc.fse.service.FseCraneService;
import com.whfc.fse.service.FseRecordService;
import com.whfc.fvs.dto.FvsStreamDTO;
import com.whfc.fvs.service.FvsDeviceService;
import com.whfc.openapi.api.fse.service.OpenApiFseCraneService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

/**
 * @ClasssName OpenApiFseCraneServiceImpl
 * @Description 塔机服务类
 * @Author hw
 * @Date 2021/2/4 16:10
 * @Version 1.0
 */
@Service
public class OpenApiFseCraneServiceImpl implements OpenApiFseCraneService {

    @DubboReference(interfaceClass = FseCraneService.class, version = "1.0.0")
    private FseCraneService fseCraneService;

    @DubboReference(interfaceClass = FseCraneDataService.class, version = "1.0.0")
    private FseCraneDataService fseCraneDataService;

    @DubboReference(interfaceClass = FseRecordService.class, version = "1.0.0")
    private FseRecordService fseRecordService;

    @DubboReference(interfaceClass = FvsDeviceService.class, version = "1.0.0")
    private FvsDeviceService fvsDeviceService;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Override
    public ListData<OpenApiFseCraneDTO> list(Integer deptId) {
        ListData<OpenApiFseCraneDTO> listData = fseCraneService.list(deptId);
        List<OpenApiFseCraneDTO> list = listData.getList();
        getVideoUrl(list);
        return listData;
    }

    @Override
    public OpenApiFseCraneDataDTO deviceInfo(String sn) {
        return fseCraneDataService.getCraneData(sn);
    }

    @Override
    public ListData<FseCraneDataLogDTO> dataReal(String sn, Date startTime, Date endTime) {
        return fseCraneDataService.log(sn, startTime, endTime);
    }

    @Override
    public ListData<OpenApiFseCraneRecordDTO> dataRecord(String sn, Date startTime, Date endTime) {
        return fseRecordService.craneRecordList(sn, startTime, endTime);
    }


    @Override
    public void dataAdd(FseCraneDataAddParam param) {
        FseCraneDataDTO fseCraneDataDTO = new FseCraneDataDTO();
        BeanUtils.copyProperties(param, fseCraneDataDTO);
        amqpTemplate.convertAndSend(QueueConst.FSE_CRANE_REAL_DATA, JSONObject.toJSONString(fseCraneDataDTO));
    }

    @Override
    public void jlznReceiveData(String data) {
        JSONObject json = JSONObject.parseObject(data);
        String dataType = json.getString("dataType");
        FseCraneDataDTO fseCraneDataDTO = new FseCraneDataDTO();
        switch (dataType){
            // 实时数据
            case FseCraneMeasurement.JLZN_REAL_DATA:
                FseCraneJlznDataDTO realData = JSONUtil.parseObject(json.toJSONString(), FseCraneJlznDataDTO.class);
                setFseCraneRealInfo(fseCraneDataDTO, realData);
                fseCraneDataDTO.setAlarmCause(getWarnDesc(fseCraneDataDTO.getAlarmCause(),realData));
                amqpTemplate.convertAndSend(QueueConst.FSE_CRANE_REAL_DATA, JSONObject.toJSONString(fseCraneDataDTO));
                break;
            // 报警数据
            case FseCraneMeasurement.WARN_DATA:
                FseCraneJlznDataDTO warnData = JSONUtil.parseObject(json.toJSONString(), FseCraneJlznDataDTO.class);
                fseCraneDataDTO.setPlatform(DevicePlatform.jlzn.name());
                // 设备唯一标识
                fseCraneDataDTO.setSn(warnData.getDevNo());
                fseCraneDataDTO.setTime(warnData.getAddtime());
                fseCraneDataDTO.setCraneStatus(changeJLZNAlarmType(warnData.getAlarmCause()));
                fseCraneDataDTO.setAlarmCause(getWarnDesc(warnData.getAlarmCause(),warnData));
                amqpTemplate.convertAndSend(QueueConst.FSE_CRANE_WARN_DATA, JSONObject.toJSONString(fseCraneDataDTO));
                break;
            // 工作数据
            case FseCraneMeasurement.WORK_DATA:
                FseCraneJlznWorkDataDTO workData = JSONUtil.parseObject(json.toJSONString(), FseCraneJlznWorkDataDTO.class);
                FseCraneRecordDTO fseCraneRecordDTO = new FseCraneRecordDTO();
                setFseCraneWorkDataInfo(workData, fseCraneRecordDTO);
                amqpTemplate.convertAndSend(QueueConst.FSE_CRANE_RECORD_DATA, JSONObject.toJSONString(fseCraneRecordDTO));
                break;
            // 设备参数
            case FseCraneMeasurement.PARM_DATA:
                FseCraneJlznParmDataDTO parmDataDTO = JSONUtil.parseObject(json.toJSONString(), FseCraneJlznParmDataDTO.class);
                FseCraneParamDTO fseCraneParamDTO = new FseCraneParamDTO();
                setFseCraneParmDataInfo(parmDataDTO, fseCraneParamDTO);
                amqpTemplate.convertAndSend(QueueConst.FSE_CRANE_PARAM_DATA, JSONObject.toJSONString(fseCraneParamDTO));
            default:
                break;
        }


    }

    /**
     * 实时数据
     * @param data
     */
    @Override
    public void tanyueRealData(String data) {
        JSONObject json = JSONObject.parseObject(data);
        FseCraneDataDTO fseCraneDataDTO = new FseCraneDataDTO();
        setTanYueRealData(json, fseCraneDataDTO);
        amqpTemplate.convertAndSend(QueueConst.FSE_CRANE_REAL_DATA, JSONObject.toJSONString(fseCraneDataDTO));
    }

    /**
     * 探越塔吊实时数据设置
     * @param json
     * @param fseCraneDataDTO
     */
    private void setTanYueRealData(JSONObject json, FseCraneDataDTO fseCraneDataDTO) {
        Integer sn = json.getInteger("eid");
        // 设备唯一标识
        fseCraneDataDTO.setSn(String.valueOf(sn));
        // 探越
        fseCraneDataDTO.setPlatform(DevicePlatform.tanyue.name());
        // 倾角
        Double angle_x = json.getDouble("angle_x");
        fseCraneDataDTO.setDipAngle(angle_x);
        // 回转
        Double round = json.getDouble("round");
        fseCraneDataDTO.setTurnAngle(round);
        // 幅度
        Double amplitude = json.getDouble("amplitude");
        fseCraneDataDTO.setRange(amplitude);
        // 力矩比
        Double moment_percent = json.getDouble("moment_percent");
        fseCraneDataDTO.setMomentRatio(moment_percent);
        // 时间
        fseCraneDataDTO.setTime(new Date());
        // 实时吊重
        Double weight = json.getDouble("weight");
        fseCraneDataDTO.setWeight(MathUtil.round(weight*0.001,3));
        // 风速
        Double wind_speed = json.getDouble("wind_speed");
        fseCraneDataDTO.setWindSpeed(wind_speed);
        // 高度
        Double height = json.getDouble("height");
        fseCraneDataDTO.setHeight(MathUtil.round(height,2));
    }

    /**
     * 报警数据
     * @param data
     */
    @Override
    public void tanyueWarnData(String data) {
        JSONObject json = JSONObject.parseObject(data);
        FseCraneDataDTO fseCraneDataDTO = new FseCraneDataDTO();
        setTanYueRealData(json, fseCraneDataDTO);
        // 报警值
        Integer type_id = json.getInteger("type_id");
        // 报警内容
        String type = json.getString("type");
        fseCraneDataDTO.setCraneStatus(changeTanYueAlarmType(type_id));
        fseCraneDataDTO.setAlarmCause(type);
        amqpTemplate.convertAndSend(QueueConst.FSE_CRANE_WARN_DATA, JSONObject.toJSONString(fseCraneDataDTO));
    }

    public Integer changeTanYueAlarmType(Integer alarmType){
        if (alarmType==3||alarmType==4||alarmType==11||alarmType==12) {
            return FseWarnRuleType.CRANE_HEIGHT_RANGE.value();
        }
        if (alarmType==5||alarmType==6||alarmType==13||alarmType==14||alarmType==41||alarmType==42) {
            return FseWarnRuleType.CRANE_RANGE.value();
        }
        if (alarmType==40||alarmType==50) {
            return FseWarnRuleType.CRANE_WEIGHT.value();
        }
        if (alarmType==15||alarmType==44) {
            return FseWarnRuleType.CRANE_FORCE_MOMENT.value();
        }
        if (alarmType==16||alarmType==46) {
            return FseWarnRuleType.CRANE_WIND_SPEED.value();
        }
        if (alarmType==45) {
            return FseWarnRuleType.CRANE_ANTI_COLLISION.value();
        }
        if (alarmType==47||alarmType==51||alarmType==52||alarmType==53||alarmType==54) {
            return FseWarnRuleType.CRANE_TURN.value();
        }
        if (alarmType==1||alarmType==2||alarmType==9||alarmType==10
                ||alarmType==17||alarmType==18||alarmType==23||alarmType==24
                ||alarmType==29||alarmType==30||alarmType==35||alarmType==36) {
            return FseWarnRuleType.CRANE_ROTARY_LIMIT.value();
        }
        return -1;
    }

    /**
     * 工作循环数据
     * @param data
     */
    @Override
    public void tanyueWorkData(String data) {
        JSONObject json = JSONObject.parseObject(data);
        FseCraneRecordDTO fseCraneRecordDTO = new FseCraneRecordDTO();
        // 设备唯一标识
        Integer sn = json.getInteger("eid");
        fseCraneRecordDTO.setSn(String.valueOf(sn));
        // 九磊智能
        fseCraneRecordDTO.setPlatform(DevicePlatform.tanyue.name());
        // 时间
        fseCraneRecordDTO.setTime(new Date());
        // 起吊开始结束时间
        Date start_time = json.getDate("start_time");
        Date end_time = json.getDate("end_time");
        fseCraneRecordDTO.setStartTime(start_time);
        fseCraneRecordDTO.setEndTime(end_time);
        // 开始结束高度
        Double start_height = json.getDouble("start_height");
        Double end_height = json.getDouble("end_height");
        fseCraneRecordDTO.setStartHeight(start_height*1.0);
        fseCraneRecordDTO.setEndHeight(end_height*1.0);
        // 开始结束幅度
        Double start_range = json.getDouble("start_range");
        Double end_range = json.getDouble("end_range");
        fseCraneRecordDTO.setStartRange(start_range);
        fseCraneRecordDTO.setEndRange(end_range);
        // 开始结束转角
        Double start_rotation_angle = json.getDouble("start_rotation_angle");
        Double end_rotation_angle = json.getDouble("end_rotation_angle");
        fseCraneRecordDTO.setStartTurnAngle(start_rotation_angle);
        fseCraneRecordDTO.setEndTurnAngle(end_rotation_angle);
        // 最大吊重
        Double weight = json.getDouble("weight");
        fseCraneRecordDTO.setMaxWeight(MathUtil.round(weight*0.001,3));
        amqpTemplate.convertAndSend(QueueConst.FSE_CRANE_RECORD_DATA, JSONObject.toJSONString(fseCraneRecordDTO));
    }

    /**
     * 九磊智能设置设备参数
     * @param parmDataDTO
     * @param fseCraneParamDTO
     */
    private void setFseCraneParmDataInfo(FseCraneJlznParmDataDTO parmDataDTO, FseCraneParamDTO fseCraneParamDTO) {
        fseCraneParamDTO.setPlatform(DevicePlatform.jlzn.name());
        // 设备唯一标识
        fseCraneParamDTO.setSn(parmDataDTO.getDevNo());
        fseCraneParamDTO.setTime(parmDataDTO.getAddtime());
        // 起重臂
        fseCraneParamDTO.setForeArmLength(parmDataDTO.getForearmLen());
        // 平衡臂
        fseCraneParamDTO.setRearArmLength(parmDataDTO.getHindarmLen());
        // 塔臂高
        fseCraneParamDTO.setTowerArmHeight(parmDataDTO.getTowerarmHeight());
        // 最大吊重
        fseCraneParamDTO.setMaxWeight(parmDataDTO.getMaxLoad()*0.001);
        // 最大力矩
        fseCraneParamDTO.setMaxMomentRatio(parmDataDTO.getMaxMof());
    }

    /**
     * 九磊智能设置工作循环数据
     * @param workData
     * @param fseCraneRecordDTO
     */
    private void setFseCraneWorkDataInfo(FseCraneJlznWorkDataDTO workData, FseCraneRecordDTO fseCraneRecordDTO) {
        // 设备唯一标识
        fseCraneRecordDTO.setSn(workData.getDevNo());
        // 九磊智能
        fseCraneRecordDTO.setPlatform(DevicePlatform.jlzn.name());
        // 时间
        fseCraneRecordDTO.setTime(workData.getAddtime());
        // 起吊开始结束时间
        fseCraneRecordDTO.setStartTime(workData.getStartTime());
        fseCraneRecordDTO.setEndTime(workData.getEndTime());
        // 开始结束高度
        fseCraneRecordDTO.setStartHeight(workData.getStartHeight());
        fseCraneRecordDTO.setEndHeight(workData.getEndHeight());
        // 开始结束幅度
        fseCraneRecordDTO.setStartRange(workData.getStartRange());
        fseCraneRecordDTO.setEndRange(workData.getEndRange());
        // 开始结束转角
        fseCraneRecordDTO.setStartTurnAngle(workData.getStartRotary());
        fseCraneRecordDTO.setEndTurnAngle(workData.getEndRotary());
        // 最大吊重
        fseCraneRecordDTO.setMaxWeight(workData.getMaxWeight()*0.001);
    }

    /**
     *九磊智能设置实时数据
     * @param fseCraneDataDTO
     * @param realData
     */
    private void setFseCraneRealInfo(FseCraneDataDTO fseCraneDataDTO, FseCraneJlznDataDTO realData) {
        // 设备唯一标识
        fseCraneDataDTO.setSn(realData.getDevNo());
        // 九磊智能
        fseCraneDataDTO.setPlatform(DevicePlatform.jlzn.name());
        // 倾角
        fseCraneDataDTO.setDipAngle(realData.getSlant());
        // 回转
        fseCraneDataDTO.setTurnAngle(realData.getRotary());
        // 幅度
        fseCraneDataDTO.setRange(realData.getRanges());
        // 力矩比
        fseCraneDataDTO.setMomentRatio(realData.getMofPct());
        // 时间
        fseCraneDataDTO.setTime(realData.getAddtime());
        // 实时吊重
        fseCraneDataDTO.setWeight(MathUtil.round(realData.getStartWeight()*0.001,3));
        // 风速
        fseCraneDataDTO.setWindSpeed(realData.getWindSpeed());
        // 高度
        fseCraneDataDTO.setHeight(realData.getHeight());
        // 报警详情
        fseCraneDataDTO.setAlarmCause(realData.getAlarmCause());
    }


    private void getVideoUrl(List<OpenApiFseCraneDTO> list) {
        if (list == null || list.isEmpty()) {
            return;
        }
        list.forEach(openApiFseLiftDTO -> {
            List<OpenApiFseDeviceDTO> videoList = openApiFseLiftDTO.getVideoList();
            if (videoList != null && !videoList.isEmpty()) {
                videoList.forEach(openApiFseDeviceDTO -> {
                    Integer deviceId = openApiFseDeviceDTO.getDeviceId();
                    FvsStreamDTO fvsStreamDTO = fvsDeviceService.getStreamUrl(deviceId);
                    openApiFseDeviceDTO.setHls(fvsStreamDTO.getHls());
                    openApiFseDeviceDTO.setHlsHd(fvsStreamDTO.getHlsHd());
                });
            }
        });
    }

    public Integer changeJLZNAlarmType(String alarmType){
        if ("111".equals(alarmType)||"112".equals(alarmType)||"113".equals(alarmType)||"114".equals(alarmType)) {
            return FseWarnRuleType.CRANE_ANTI_COLLISION.value();
        }
        if ("12".equals(alarmType)) {
            return FseWarnRuleType.CRANE_WEIGHT.value();
        }
        if ("13".equals(alarmType)) {
            return FseWarnRuleType.CRANE_FORCE_MOMENT.value();
        }
        if ("14".equals(alarmType)) {
            return FseWarnRuleType.CRANE_TURN.value();
        }
        if ("15".equals(alarmType)) {
            return FseWarnRuleType.CRANE_WIND_SPEED.value();
        }
        if ("101".equals(alarmType)) {
            return FseWarnRuleType.CRANE_RANGE.value();
        }
        if ("102".equals(alarmType)) {
            return FseWarnRuleType.CRANE_HEIGHT_RANGE.value();
        }
        if ("103".equals(alarmType)) {
            return FseWarnRuleType.CRANE_ROTARY_LIMIT.value();
        }
        return -1;
    }

    private String getWarnDesc(String status,FseCraneJlznDataDTO realData){
        if (!StringUtils.hasText(status)) {
            return "";
        }
        switch (status){
            case "111":
            case "112":
            case "113":
            case "114":
                return "碰撞报警";
            case "12":
                return "重量报警: "+MathUtil.round(realData.getStartWeight()*0.001,3)+"吨";
            case "13":
                return "力矩报警: "+realData.getMofPct()+"%";
            case "14":
                return "倾斜报警: "+realData.getSlant()+"°";
            case "15":
                return "风速报警: "+realData.getWindSpeed()+"m/s";
            case "101":
                return "幅度限位报警: "+realData.getRanges()+"m";
            case "102":
                return "高度限位报警: "+realData.getHeight()+"m";
            case "103":
                return "回转限位报警: "+realData.getRotary()+"°";
            default:
                return "";

        }
    };


}
